package gui.parser;

import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.lang.reflect.Constructor;
import java.util.LinkedList;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserFactory;

import gui.Context;
import gui.view.View;
import gui.view.ViewGroup;

/**
 * 布局文件解析器
 * 
 * @author chenj_000
 *
 */
public class LayoutParser {

	public LayoutParser(int layoutId) {
		buildLayoutFromID(layoutId);
	}

	public View getLayout() {
		return mainView;
	}

	private View mainView;
	private LinkedList<View> viewStack = new LinkedList<>();

	public View buildLayoutFromID(int layoutId) {
		InputStream layout = Context.getResource().getLayout(layoutId);
		if (layout == null)
			throw new RuntimeException();
		parser(new InputStreamReader(layout));
		return mainView;
	}

	private void parser(Reader reader) {
		try {
			XmlPullParser parser = XmlPullParserFactory.newInstance().newPullParser();
			parser.setInput(reader);
			int eventType = parser.getEventType();
			String tagName;
			while (eventType != XmlPullParser.END_DOCUMENT) {
				tagName = parser.getName();
				switch (eventType) {
				case XmlPullParser.START_TAG: {
					startTag(tagName, parser);
				}
					break;
				case XmlPullParser.END_TAG: {
					endTag(tagName, parser);
				}
					break;
				case XmlPullParser.TEXT: {
				}
					break;
				}
				eventType = parser.next();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private void endTag(String tagName, XmlPullParser parser) {
		viewStack.pop();
	}

	private void startTag(String tagName, XmlPullParser parser) {
		try {
			Attr attr = new Attr();
			for (int i = 0; i < parser.getAttributeCount(); i++) {
				attr.addAttr(parser.getAttributeName(i), parser.getAttributeValue(i));
			}
			Constructor<?> declaredConstructor = buildClass(tagName).getDeclaredConstructor(Attr.class);
			declaredConstructor.setAccessible(true);
			View view = (View) declaredConstructor.newInstance(attr);
			if (mainView == null)
				mainView = view;
			else {
				((ViewGroup) viewStack.getFirst()).addChild(view);
			}
			viewStack.push(view);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private static Class<?> buildClass(String name) {
		String className = "gui.view." + name;
		Class<?> cls = null;
		try {
			cls = Class.forName(className);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		return cls;
	}
}
